package force;

import java.util.ArrayList;
import java.util.List;
import object.mass.Mass;
import sim.Simulation;

/**
 * A class that applies global forces to Masses and toggles them on and off.
 * Each Simulation has an associated GlobalForceApplier, since global forces
 * apply to everything in the Simulation.
 * 
 * @author Niel Lebeck and Wynne Lok
 *
 */

public class GlobalForceApplier {
    private static final int TOP_WALL = 0;
    private static final int RIGHT_WALL = 1;
    private static final int BOTTOM_WALL = 2;
    private static final int LEFT_WALL = 3;
    
    private Simulation mySim;
    private List<GlobalForceSource> myGlobalForceList;
    
    /**
     * 
     * @param s Simulation
     */
    public GlobalForceApplier(Simulation s) {
        myGlobalForceList = new ArrayList<GlobalForceSource>();

        //add default forces
        myGlobalForceList.add(new Gravity());
        myGlobalForceList.add(new Viscosity());
        myGlobalForceList.add(new CenterMass());
        myGlobalForceList.add(new WallForce(TOP_WALL));
        myGlobalForceList.add(new WallForce(RIGHT_WALL));
        myGlobalForceList.add(new WallForce(BOTTOM_WALL));
        myGlobalForceList.add(new WallForce(LEFT_WALL));
        
        mySim = s;
    }
    
    /**
     * Add a global force.
     * @param gf force to add
     */
    public void addGlobalForce(GlobalForceSource gf) {
        myGlobalForceList.add(gf);
    }
    
    /**
     * Apply all of the global forces to the given Mass
     * @param m Mass being acted on.
     */
    public void applyForces(Mass m) {
        Force totalGlobalForce = new Force(0, 0);
        for (GlobalForceSource gf : myGlobalForceList) {
            totalGlobalForce.sum(gf.getForce(m, mySim));
        }
        m.applyForce(totalGlobalForce);
    }
    
    /**
     * Check each global force to see if it is affected by
     * the keycode, and if so, toggle it.
     * @param keycode the key code
     */
    public void toggleForce(int keycode) {
        for (GlobalForceSource gf : myGlobalForceList) {
            gf.toggle(keycode);
        }
    }
}
